<?php
declare(strict_types=1);

namespace So;

use Hyperf\HttpServer\Request as HyperfRequest;

/**
 * 新增Request方法
 * @author Saopig <1306222220@qq.com>
 */
class Request extends HyperfRequest
{

    /**
     * 获取用户IP，如果为nginx转发则获取真实客户端IP
     * @return string
     */
    public function ip(): string
    {
        $ip = '';
        if ($this->hasHeader('x-real-ip')) {
            $ip = $this->getHeaderLine('x-real-ip');
        } elseif ($this->hasHeader('x-forwarded-for')) {
            $ip = $this->getHeaderLine('x-forwarded-for');
        } elseif ($this->hasHeader('remote-host')) {
            $ip = $this->getHeaderLine('remote-host');
        }
        if ($ip == '127.0.0.1') {
            $headers = $this->getHeaders();
            $ip = isset($headers['remote-addr']) && $headers['remote-addr'] ? $headers['remote-addr'] : $ip;
        }
        return $ip ?: '0.0.0.0';
    }

    /**
     * 获取path路径
     * @param false $array
     * @return array|string
     */
    public function getPath($array = false): array|string
    {
        $path = $this->path();
        $path = array_filter(explode('/', $path));
        $count_path = count($path);
        if ($count_path >= 2) {
            $controller = $path[(count($path) - 2)];
            $action = $path[(count($path) - 1)];
            return $array ? [$controller, $action] : $controller . '/' . $action;
        }
        return $array ? [] : '';
    }

    /**
     * 安全过滤提交参数
     * @param null $key
     * @param string $default
     * @param string[] $filter
     * @return string|array|int
     */
    public function filter($key = null, $default = '', $filter = ['trim', 'strip_tags', 'htmlspecialchars']): string|array|int
    {
        if (is_string($filter)) {
            $filter = [$filter];
        }
        $type_array = [
            'f' => "float", 's' => "string", 'a' => "array", 'd' => "integer", 'b' => "bool"
        ];
        if ($key) {
            $keys = array_filter(explode('/', $key));
            $type = isset($keys[1]) && isset($type_array[$keys[1]]) ? $keys[1] : false;
            $key = $type ? $keys[0] : $key;
            $value = $this->input($key, $default) ?: $default;
        } else {
            $value = $this->all();
        }
        if ($filter) {
            foreach ($filter as $k => $v) {
                if (is_array($value)) {
                    foreach ($value as $a => &$b) {
                        is_string($b) && $b = call_user_func($v, $b);
                    }
                } else {
                    $value = call_user_func($v, $value);
                }
            }
        }
        if (isset($type) && $type) settype($value, $type_array[$keys[1]]);
        return $value;
    }
}